/* HTTP GET Example using plain POSIX sockets

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"

#include "esp_netif.h"
#include "esp_tls.h"
#include "esp_http_client.h"
#include "cJSON.h"

#include "http_request.h"
#include <time.h>
#include <sys/time.h>


static const char *TAG = "HTTP_CLIENT";
//http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp//不能用了
//https://acs.m.taobao.com/gw/mtop.common.getTimestamp/ //美团获取时间api接口2 能用
//https://cube.meituan.com/ipromotion/cube/toc/component/base/getServerCurrentTime //美团获取时间api接口
#define TIME_URL "http://acs.m.taobao.com/gw/mtop.common.getTimestamp/" //淘宝获取时间api接口
#define FANS_URL "https://api.bilibili.com/x/relation/stat?vmid=59395298&jsonp=jsonp" //api接口

bool set_time_flag = 0;
int fans_type = 0;

/* 字符串转整形 */
unsigned int stringToint(char source[], unsigned char startBit, unsigned char len)
{
	unsigned char i;
	unsigned int temp1, temp2;
	temp2 = 0;
	for (i = startBit; i < len; i++)
	{
		temp1 = source[i] - '0';
		temp2 = temp2 * 10;
		temp2 += temp1;
	}

	return temp2;
}

static void cjson_time_info(char *text)
{
    cJSON *root,*psub;
    char time[20];
    struct timeval setTv;

    //截取有效json
    char *index=strchr(text,'{');
    strcpy(text,index);
    root = cJSON_Parse(text);
    if(root!=NULL)
    {
        ESP_LOGI(TAG, "start analysis json..");
        psub = cJSON_GetObjectItem(root, "data");
        if(psub != NULL)
        {
            cJSON *nowtime = cJSON_GetObjectItem(psub, "t");
            ESP_LOGI(TAG, "start analysis sprintf..");
            //now = localtime(nowtime);
            sprintf(time,"%s",nowtime->valuestring);//从cJSON数据中提取出时间戳
            ESP_LOGI(TAG,"sysTime:%s",time);

            setTv.tv_sec = stringToint(time,0,10);//从time字符串数据中提取出时间戳 单位秒，后3位毫秒舍弃
            setTv.tv_usec = stringToint(time,10,3);//从time字符串数据中提取出时间戳 单位毫秒，前10位秒舍弃
            setTv.tv_usec = setTv.tv_usec + 40;//补偿时间差
            setTv.tv_usec = setTv.tv_usec * 1000;//把毫秒 转 微秒
            settimeofday(&setTv,0);//设置时间
            ESP_LOGI(TAG,"get time done!");
            set_time_flag = 1;
        }
    }
    cJSON_Delete(root);

    int len = strlen(time);
    if(len < 11){
        return;
    }
}

//事件回调
static esp_err_t _http_time_event_handle(esp_http_client_event_t *evt)
{
    switch(evt->event_id) {
        case HTTP_EVENT_ON_DATA://接收数据事件
            ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
            if (!esp_http_client_is_chunked_response(evt->client)) {
                #if PRINTEN
                printf("%.*s\n", evt->data_len, (char*)evt->data);
                #endif
                if(evt->data_len < 110) cjson_time_info((char*)evt->data);
            }
            break;
        case HTTP_EVENT_ERROR:
            break;
        case HTTP_EVENT_ON_CONNECTED:
            break;
        case HTTP_EVENT_HEADERS_SENT:
            break;
        case HTTP_EVENT_ON_HEADER:
            break;
        case HTTP_EVENT_DISCONNECTED:
            break;
        case HTTP_EVENT_ON_FINISH:
            break;
        case HTTP_EVENT_REDIRECT:
            break;
    }
    return ESP_OK;
}

void http_time_get()
{
    //http client配置
    esp_http_client_config_t config = {
        .method = HTTP_METHOD_GET, //get请求
        .url = TIME_URL,
        .event_handler = _http_time_event_handle,//注册时间回调
        .skip_cert_common_name_check = true,
    };
	esp_http_client_handle_t time_client = esp_http_client_init(&config);//初始化配置
	esp_err_t err = esp_http_client_perform(time_client);//执行请求

	if(err == ESP_OK)
	{
		ESP_LOGI(TAG, "Status = %d, content_length = %lld",
				esp_http_client_get_status_code(time_client),//状态码
				esp_http_client_get_content_length(time_client));//数据长度
	}
	esp_http_client_cleanup(time_client);//断开并释放资源
}

QueueHandle_t http_get_event_queue;

void http_set_type(HTTP_GET_TYPE_E type){
    HTTP_GET_EVENT_T evt;
	evt.type = type;
	xQueueSend(http_get_event_queue, &evt, 10);
}

static void http_get_task(void *pvParameters)
{

    while(1) 
    {
        http_time_get(8,0);
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        if(set_time_flag == 1)
        {
            set_time_flag = 0;
        }
    }
    vTaskDelete(NULL); 
    ESP_LOGI(TAG,"close http get task");
}

void http_request_init(void)
{
	http_get_event_queue = xQueueCreate(10, sizeof(HTTP_GET_EVENT_T));
    xTaskCreate(&http_get_task, "http_get_task", 4096, NULL, 5, NULL);
}
